<?php

class Workset_Sphinx_XmlPipe extends Workset_Sphinx_XmlPipe_Entity {

    protected $_header = '<?xml version="1.0" encoding="utf-8"?>';

    protected $_fields = array();

    protected $_attrs = array();

    protected $_documents = array();

    protected $_killList = array();

    public function setFields(array $fields) {
        $this->_fields = $fields;
    }

    public function setAttributes(array $attrs) {
        $this->_attrs = $attrs;
    }

    public function addAttribute($name, array $options = null) {
        if (empty($options)) {
            $options = array(
                'name' => $name,
                'type' => 'int',
                'bits' => 32
            );
        } else {
            $options['name'] = $name;
        }

        $this->_attrs[] = $options;
    }

    public function addDocument($spec, $fields = null) {
        if ($spec instanceof Workset_Sphinx_XmlPipe_Document) {
            $this->_documents[] = $spec;
        } elseif (null !== $fields) {
            $this->_documents[] = new Workset_Sphinx_XmlPipe_Document($spec, $fields);
        }
    }

    public function clearDocuments() {
        $this->_documents = array();
    }

    public function removeDocument($id) {
        $this->_killList[] = (int)$id;
    }

    public function clearKillList() {
        $this->_killList = array();
    }

    public function send($part = null) {
        echo $this->toString();
    }

    public function toString($part = null) {

        if (is_string($part)) {
            $method = '_build' . ucfirst($part);
            return $this->{$method}();
        }

        $xml = $this->_buildHeader();

        $xml .= $this->_buildDocsetOpen();

        $xml .= $this->_buildSchema();
        $xml .= $this->_buildDocuments();
        $xml .= $this->_buildKillList();

        $xml .= $this->_buildDocsetClose();

        return $xml;
    }

    public function __toString() {
        $this->toString();
    }

    protected function _buildHeader() {
        return $this->_header . "\r\n";
    }

    protected function _buildDocsetOpen() {
        return '<' . $this->_namespace . ":docset>\r\n";
    }

    protected function _buildDocsetClose() {
        return '</' . $this->_namespace . ':docset>';
    }

    protected function _buildSchema() {
        $parts = array('<' . $this->_namespace . ':schema>');

        foreach ($this->_fields as $value) {
            $parts[] = "\t<" . $this->_namespace . ':field name="' . $value . '" />';
        }

        foreach ($this->_attrs as $key => $value) {

            if (!is_array($value)) {
               $value = array(
                   'name' => $key,
                   'type' => $value
               ); 
            }

            $str = array();

            foreach ($value as $k => $v) {
                $v = htmlentities($v);
                $str[] = $k . '="' . $v . '"';
            }

            $value = implode(' ', $str);

            $parts[] = "\t<" . $this->_namespace . ':attr ' . $value . ' />';
        }

        $parts[] = '</' . $this->_namespace . ":schema>\r\n";

        return implode("\r\n", $parts);
    }

    protected function _buildDocuments() {
        $parts = array();

        foreach ($this->_documents as $doc) {
            $parts[] = $doc->toString();
        }

        return implode('', $parts);
    }

    protected function _buildKillList() {
        $parts = array('<' . $this->_namespace . ':killlist>');

        foreach ($this->_killList as $id) {
            $parts[] = "\t<id>" . $id . '</id>';
        }

        $parts[] = '</' . $this->_namespace . ":killlist>\r\n";

        return implode("\r\n", $parts);
    }

}
